package com.service.Impl;

import com.dto.LotteryRecordWithPrizeDto;
import com.entity.*;
import com.exception.AddException;
import com.exception.DateNotFoundException;
import com.exception.UpdateException;
import com.github.pagehelper.PageInfo;
import com.mapper.*;
import com.service.LotteryDrawRecordService;
import com.utils.OrderNoGenerator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName LotteryDrawRecordServiceImpl
 * @Description 抽奖记录业务层实现类
 * @Author Kx
 * @Date 2025/6/18 11:28
 * @Version 1.0
 */
@Service("/lotteryDrawRecordServices")
public class LotteryDrawRecordServiceImpl implements LotteryDrawRecordService {
    private final LotteryDrawRecordMapper lotteryDrawRecordMapper;
    private final LotteryPrizeMapper lotteryPrizeMapper;
    private final LotteryOrderMapper lotteryOrderMapper;
    private final UserMapper userMapper;
    private final AccountMapper accountMapper;
    private final AccountXpInfoMapper accountXpInfoMapper;
    private final UserCouponMapper userCouponMapper;
    private final CouponMapper couponMapper;

    public LotteryDrawRecordServiceImpl(LotteryDrawRecordMapper lotteryDrawRecordMapper, LotteryPrizeMapper lotteryPrizeMapper, LotteryOrderMapper lotteryOrderMapper, UserMapper userMapper, AccountMapper accountMapper, AccountXpInfoMapper accountXpInfoMapper, UserCouponMapper userCouponMapper, CouponMapper couponMapper) {
        this.lotteryDrawRecordMapper = lotteryDrawRecordMapper;
        this.lotteryPrizeMapper = lotteryPrizeMapper;
        this.lotteryOrderMapper = lotteryOrderMapper;
        this.userMapper = userMapper;
        this.accountMapper = accountMapper;
        this.accountXpInfoMapper = accountXpInfoMapper;
        this.userCouponMapper = userCouponMapper;
        this.couponMapper = couponMapper;
    }

    /**
     * @author: kx
     * @date: 2025/6/18 15:29
     * @param name : 奖品名称
     * @return int
     * @description: 从奖品名称中解析积分值
    */
    private int parsePointValueFromName(String name) {
        // 1. 编译正则表达式：匹配"数字+积分"模式
        Pattern pattern = Pattern.compile("(\\d+)积分");

        // 2. 创建Matcher对象，用于在name中查找匹配项
        Matcher matcher = pattern.matcher(name);

        // 3. 判断是否找到匹配项
        if (matcher.find()) {
            // 4. 提取第一个捕获组（即括号内的数字部分）并转为整数
            return Integer.parseInt(matcher.group(1));
        }

        // 5. 未找到匹配项时返回0（实际应抛异常）
        return 0;
    }

    /**
     * @author: kx
     * @date: 2025/6/18 11:30
     * @param lotteryDrawRecords : 抽奖记录列表
     * @param address : 收货地址
     * @description: 添加抽奖记录
    */
    @Transactional
    @Override
    public synchronized void addLotteryDrawRecord(List<LotteryDrawRecord> lotteryDrawRecords, String address) {
        for (LotteryDrawRecord lotteryDrawRecord : lotteryDrawRecords) {
            try {
                // 设置抽奖时间
                lotteryDrawRecord.setDrawTime(LocalDateTime.now());
                // 添加抽奖奖品记录
                lotteryDrawRecordMapper.addLotteryDrawRecord(lotteryDrawRecord);
            } catch (Exception e) {
                e.printStackTrace();
                throw new AddException(1002, "添加抽奖记录失败");
            }
            // 获取奖品信息
            LotteryPrize lotteryPrize = lotteryPrizeMapper.getLotteryPrizeById(lotteryDrawRecord.getPrizeId());
            // 判断奖品库存
            if ((lotteryPrize.getType() == 0 || lotteryPrize.getType() == 2) && lotteryPrize.getStock() <= 0) {
                throw new UpdateException(1003, "奖品库存不足");
            }

            if (lotteryPrize.getType() == 0) {
                // 封装订单信息
                LotteryOrder lotteryOrder = new LotteryOrder();
                lotteryOrder.setId(OrderNoGenerator.generateOrderNo()); // 订单编号
                lotteryOrder.setUserId(lotteryDrawRecord.getUserId()); // 用户id
                lotteryOrder.setPrizeId(lotteryDrawRecord.getPrizeId()); // 奖品id
                lotteryOrder.setAddress(address); // 收货地址
                lotteryOrder.setCreateTime(lotteryDrawRecord.getDrawTime()); // 创建时间
                // 添加奖品订单信息
                try {
                    lotteryOrderMapper.addLotteryOrder(lotteryOrder);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new AddException(1002, "添加奖品订单信息失败");
                }
                try {
                    // 设置奖品库存
                    lotteryPrize.setStock(lotteryPrize.getStock() - 1);
                    // 修改奖品库存
                    lotteryPrizeMapper.updateLotteryPrize(lotteryPrize);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new UpdateException(1003, "修改奖品信息失败");
                }
            } else if (lotteryPrize.getType() == 1) {
                // 增加用户积分
                // 1. 获取用户信息
                User user = userMapper.findByUserId(lotteryDrawRecord.getUserId());
                // 2. 获取账号信息
                Account account = accountMapper.findById(user.getAccountId());
                // 3. 获取账号积分信息
                AccountXpInfo accountXpInfo = accountXpInfoMapper.findByAccountId(account.getAccountId());
                // 4. 获取奖品积分值
                int pointValue = parsePointValueFromName(lotteryPrize.getName());
                // 5. 增加用户积分
                try {
                    accountXpInfoMapper.addXpPointsToAccountById(account.getAccountId(), pointValue);
                } catch (Exception e) {
                    throw new UpdateException(1003, "修改用户积分失败");
                }
            } else if (lotteryPrize.getType() == 2) {
                // 1. 优惠券信息
                Coupon coupon = couponMapper.findById(lotteryPrize.getTargetId());
                // 2. 封装用户优惠券信息
                UserCoupon userCoupon = new UserCoupon();
                userCoupon.setUserId(lotteryDrawRecord.getUserId()); // 用户id
                userCoupon.setCouponId(lotteryPrize.getTargetId()); // 优惠券id
                userCoupon.setOrderId(null); // 使用的订单id
                userCoupon.setStartTime(LocalDateTime.now()); // 有效期开始时间
                userCoupon.setEndTime(userCoupon.getStartTime().plusDays(coupon.getValidDays())); // 有效期结束时间(有效期开始时间+有效期天数)
                userCoupon.setUsedTime(null); // 使用时间
                userCoupon.setCreateTime(LocalDateTime.now()); // 领取时间
                // 3. 添加用户优惠券信息
                try {
                    userCouponMapper.addUserCoupon(userCoupon);
                } catch (Exception e) {
                    throw new AddException(1002, "添加用户优惠券信息失败");
                }
                try {
                    // 4. 修改奖品库存
                    // 设置奖品库存
                    lotteryPrize.setStock(lotteryPrize.getStock() - 1);
                    lotteryPrizeMapper.updateLotteryPrize(lotteryPrize);
                } catch (Exception e) {
                    throw new UpdateException(1003, "修改奖品信息失败");
                }
            }
        }
    }

    /**
     * @author: kx
     * @date: 2025/6/18 20:00
     * @param userId : 用户id
     * @return java.util.List<com.dto.LotteryRecordWithPrizeDto>
     * @description: 根据用户id查询该用户的抽奖记录
    */
    @Override
    public List<LotteryRecordWithPrizeDto> findByUserId(Integer userId) {
        List<LotteryRecordWithPrizeDto> list = new ArrayList<>();

        // 获取指定用户的抽奖记录
        List<LotteryDrawRecord> lotteryDrawRecords = lotteryDrawRecordMapper.findByUserId(userId);
        // 获取该用户信息
        User user = userMapper.findByUserId(userId);

        for (LotteryDrawRecord lotteryDrawRecord : lotteryDrawRecords) {
            LotteryRecordWithPrizeDto lotteryRecordWithPrizeDto = new LotteryRecordWithPrizeDto();
            // 设置用户信息
            lotteryRecordWithPrizeDto.setUser(user);
            // 设置奖品信息
            lotteryRecordWithPrizeDto.setLotteryPrize(lotteryPrizeMapper.getLotteryPrizeById(lotteryDrawRecord.getPrizeId()));
            // 添加到集合中
            list.add(lotteryRecordWithPrizeDto);
        }
        return list;
    }

    /**
     * @author: kx
     * @date: 2025/6/18 20:26
     * @param pageNum : 页码
     * @param pageSize : 每页显示的记录数
     * @return com.github.pagehelper.PageInfo<com.entity.LotteryDrawRecord>
     * @description: 分页查询所有抽奖记录
    */
    @Override
    public PageInfo<LotteryRecordWithPrizeDto> findPagedAllRecords(Integer pageNum, Integer pageSize) {
        if (lotteryDrawRecordMapper.findPagedAllRecords(pageNum, pageSize) != null) {
            // 获取所有抽奖记录列表
            List<LotteryDrawRecord> lotteryDrawRecords = lotteryDrawRecordMapper.findPagedAllRecords(pageNum, pageSize);
            // 创建DTO列表
            List<LotteryRecordWithPrizeDto> list = new ArrayList<>();
            for (LotteryDrawRecord lotteryDrawRecord : lotteryDrawRecords) {
                LotteryRecordWithPrizeDto lotteryRecordWithPrizeDto = new LotteryRecordWithPrizeDto();
                // 设置用户信息
                lotteryRecordWithPrizeDto.setUser(userMapper.findByUserId(lotteryDrawRecord.getUserId()));
                // 设置奖品记录信息
                lotteryRecordWithPrizeDto.setLotteryPrize(lotteryPrizeMapper.getLotteryPrizeById(lotteryDrawRecord.getPrizeId()));
                // 添加到集合中
                list.add(lotteryRecordWithPrizeDto);
            }
            return new PageInfo<>(list);
        }
        throw new DateNotFoundException(1001, "没有查询到所有抽奖记录");
    }

    /**
     * @author: kx
     * @date: 2025/6/19 11:04
     * @param keyword : 关键字
     * @param pageNum : 页码
     * @param pageSize : 每页显示的记录数
     * @return com.github.pagehelper.PageInfo<com.dto.LotteryRecordWithPrizeDto>
     * @description: 根据用户名称模糊分页查询抽奖记录
    */
    @Override
    public PageInfo<LotteryRecordWithPrizeDto> findRecordsByKeyword(String keyword, Integer pageNum, Integer pageSize) {
        if (lotteryDrawRecordMapper.findRecordsByKeyword(keyword, pageNum, pageSize) != null) {
            // 获取该用户的所有抽奖记录
            List<LotteryDrawRecord> lotteryDrawRecords = lotteryDrawRecordMapper.findRecordsByKeyword(keyword, pageNum, pageSize);
            // 创建集合
            List<LotteryRecordWithPrizeDto> list = new ArrayList<>();
            for (LotteryDrawRecord lotteryDrawRecord : lotteryDrawRecords) {
                // 创建传输对象
                LotteryRecordWithPrizeDto lotteryRecordWithPrizeDto = new LotteryRecordWithPrizeDto();
                // 设置用户信息
                lotteryRecordWithPrizeDto.setUser(userMapper.findByUserId(lotteryDrawRecord.getUserId()));
                // 设置奖品记录信息
                lotteryRecordWithPrizeDto.setLotteryPrize(lotteryPrizeMapper.getLotteryPrizeById(lotteryDrawRecord.getPrizeId()));
                // 添加到集合中
                list.add(lotteryRecordWithPrizeDto);
            }
            return new PageInfo<>(list);
        }
        throw new DateNotFoundException(1001, "没有查询到该用户的所有抽奖记录");
    }
}
